//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2021 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto/tree/main/CodeGenerator. DO NOT EDIT.

import Foundation
import SotoCore

extension DLM {
    // MARK: Enums

    public enum EventSourceValues: String, CustomStringConvertible, Codable {
        case managedCwe = "MANAGED_CWE"
        public var description: String { return self.rawValue }
    }

    public enum EventTypeValues: String, CustomStringConvertible, Codable {
        case sharesnapshot = "shareSnapshot"
        public var description: String { return self.rawValue }
    }

    public enum GettablePolicyStateValues: String, CustomStringConvertible, Codable {
        case disabled = "DISABLED"
        case enabled = "ENABLED"
        case error = "ERROR"
        public var description: String { return self.rawValue }
    }

    public enum IntervalUnitValues: String, CustomStringConvertible, Codable {
        case hours = "HOURS"
        public var description: String { return self.rawValue }
    }

    public enum LocationValues: String, CustomStringConvertible, Codable {
        case cloud = "CLOUD"
        case outpostLocal = "OUTPOST_LOCAL"
        public var description: String { return self.rawValue }
    }

    public enum PolicyTypeValues: String, CustomStringConvertible, Codable {
        case ebsSnapshotManagement = "EBS_SNAPSHOT_MANAGEMENT"
        case eventBasedPolicy = "EVENT_BASED_POLICY"
        case imageManagement = "IMAGE_MANAGEMENT"
        public var description: String { return self.rawValue }
    }

    public enum ResourceLocationValues: String, CustomStringConvertible, Codable {
        case cloud = "CLOUD"
        case outpost = "OUTPOST"
        public var description: String { return self.rawValue }
    }

    public enum ResourceTypeValues: String, CustomStringConvertible, Codable {
        case instance = "INSTANCE"
        case volume = "VOLUME"
        public var description: String { return self.rawValue }
    }

    public enum RetentionIntervalUnitValues: String, CustomStringConvertible, Codable {
        case days = "DAYS"
        case months = "MONTHS"
        case weeks = "WEEKS"
        case years = "YEARS"
        public var description: String { return self.rawValue }
    }

    public enum SettablePolicyStateValues: String, CustomStringConvertible, Codable {
        case disabled = "DISABLED"
        case enabled = "ENABLED"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct Action: AWSEncodableShape & AWSDecodableShape {
        /// The rule for copying shared snapshots across Regions.
        public let crossRegionCopy: [CrossRegionCopyAction]
        /// A descriptive name for the action.
        public let name: String

        public init(crossRegionCopy: [CrossRegionCopyAction], name: String) {
            self.crossRegionCopy = crossRegionCopy
            self.name = name
        }

        public func validate(name: String) throws {
            try self.crossRegionCopy.forEach {
                try $0.validate(name: "\(name).crossRegionCopy[]")
            }
            try self.validate(self.crossRegionCopy, name: "crossRegionCopy", parent: name, max: 3)
            try self.validate(self.crossRegionCopy, name: "crossRegionCopy", parent: name, min: 0)
            try self.validate(self.name, name: "name", parent: name, max: 120)
            try self.validate(self.name, name: "name", parent: name, min: 0)
            try self.validate(self.name, name: "name", parent: name, pattern: "[0-9A-Za-z _-]+")
        }

        private enum CodingKeys: String, CodingKey {
            case crossRegionCopy = "CrossRegionCopy"
            case name = "Name"
        }
    }

    public struct CreateLifecyclePolicyRequest: AWSEncodableShape {
        /// A description of the lifecycle policy. The characters ^[0-9A-Za-z _-]+$ are supported.
        public let description: String
        /// The Amazon Resource Name (ARN) of the IAM role used to run the operations specified by the lifecycle policy.
        public let executionRoleArn: String
        /// The configuration details of the lifecycle policy.
        public let policyDetails: PolicyDetails
        /// The desired activation state of the lifecycle policy after creation.
        public let state: SettablePolicyStateValues
        /// The tags to apply to the lifecycle policy during creation.
        public let tags: [String: String]?

        public init(description: String, executionRoleArn: String, policyDetails: PolicyDetails, state: SettablePolicyStateValues, tags: [String: String]? = nil) {
            self.description = description
            self.executionRoleArn = executionRoleArn
            self.policyDetails = policyDetails
            self.state = state
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 500)
            try self.validate(self.description, name: "description", parent: name, min: 0)
            try self.validate(self.description, name: "description", parent: name, pattern: "[0-9A-Za-z _-]+")
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, max: 2048)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, min: 0)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, pattern: "arn:aws(-[a-z]{1,3}){0,2}:iam::\\d+:role/.*")
            try self.policyDetails.validate(name: "\(name).policyDetails")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "[\\p{all}]*")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case executionRoleArn = "ExecutionRoleArn"
            case policyDetails = "PolicyDetails"
            case state = "State"
            case tags = "Tags"
        }
    }

    public struct CreateLifecyclePolicyResponse: AWSDecodableShape {
        /// The identifier of the lifecycle policy.
        public let policyId: String?

        public init(policyId: String? = nil) {
            self.policyId = policyId
        }

        private enum CodingKeys: String, CodingKey {
            case policyId = "PolicyId"
        }
    }

    public struct CreateRule: AWSEncodableShape & AWSDecodableShape {
        /// The schedule, as a Cron expression. The schedule interval must be between 1 hour and 1 year. For more information, see Cron expressions in the Amazon CloudWatch User Guide.
        public let cronExpression: String?
        /// The interval between snapshots. The supported values are 1, 2, 3, 4, 6, 8, 12, and 24.
        public let interval: Int?
        /// The interval unit.
        public let intervalUnit: IntervalUnitValues?
        /// Specifies the destination for snapshots created by the policy. To create snapshots in the same Region as the source resource, specify CLOUD. To create snapshots on the same Outpost as the source resource, specify OUTPOST_LOCAL. If you omit this parameter, CLOUD is used by default. If the policy targets resources in an AWS Region, then you must create snapshots in the same Region as the source resource.  If the policy targets resources on an Outpost, then you can create snapshots on the same Outpost as the source resource, or in the Region of that Outpost.
        public let location: LocationValues?
        /// The time, in UTC, to start the operation. The supported format is hh:mm. The operation occurs within a one-hour window following the specified time. If you do not specify a time, Amazon DLM selects a time within the next 24 hours.
        public let times: [String]?

        public init(cronExpression: String? = nil, interval: Int? = nil, intervalUnit: IntervalUnitValues? = nil, location: LocationValues? = nil, times: [String]? = nil) {
            self.cronExpression = cronExpression
            self.interval = interval
            self.intervalUnit = intervalUnit
            self.location = location
            self.times = times
        }

        public func validate(name: String) throws {
            try self.validate(self.cronExpression, name: "cronExpression", parent: name, max: 106)
            try self.validate(self.cronExpression, name: "cronExpression", parent: name, min: 17)
            try self.validate(self.cronExpression, name: "cronExpression", parent: name, pattern: "cron\\([^\\n]{11,100}\\)")
            try self.validate(self.interval, name: "interval", parent: name, min: 1)
            try self.times?.forEach {
                try validate($0, name: "times[]", parent: name, max: 5)
                try validate($0, name: "times[]", parent: name, min: 5)
                try validate($0, name: "times[]", parent: name, pattern: "^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$")
            }
            try self.validate(self.times, name: "times", parent: name, max: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case cronExpression = "CronExpression"
            case interval = "Interval"
            case intervalUnit = "IntervalUnit"
            case location = "Location"
            case times = "Times"
        }
    }

    public struct CrossRegionCopyAction: AWSEncodableShape & AWSDecodableShape {
        /// The encryption settings for the copied snapshot.
        public let encryptionConfiguration: EncryptionConfiguration
        public let retainRule: CrossRegionCopyRetainRule?
        /// The target Region.
        public let target: String

        public init(encryptionConfiguration: EncryptionConfiguration, retainRule: CrossRegionCopyRetainRule? = nil, target: String) {
            self.encryptionConfiguration = encryptionConfiguration
            self.retainRule = retainRule
            self.target = target
        }

        public func validate(name: String) throws {
            try self.encryptionConfiguration.validate(name: "\(name).encryptionConfiguration")
            try self.retainRule?.validate(name: "\(name).retainRule")
            try self.validate(self.target, name: "target", parent: name, max: 2048)
            try self.validate(self.target, name: "target", parent: name, min: 0)
            try self.validate(self.target, name: "target", parent: name, pattern: "^[\\w:\\-\\/\\*]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case encryptionConfiguration = "EncryptionConfiguration"
            case retainRule = "RetainRule"
            case target = "Target"
        }
    }

    public struct CrossRegionCopyRetainRule: AWSEncodableShape & AWSDecodableShape {
        /// The amount of time to retain each snapshot. The maximum is 100 years. This is equivalent to 1200 months, 5200 weeks, or 36500 days.
        public let interval: Int?
        /// The unit of time for time-based retention.
        public let intervalUnit: RetentionIntervalUnitValues?

        public init(interval: Int? = nil, intervalUnit: RetentionIntervalUnitValues? = nil) {
            self.interval = interval
            self.intervalUnit = intervalUnit
        }

        public func validate(name: String) throws {
            try self.validate(self.interval, name: "interval", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case interval = "Interval"
            case intervalUnit = "IntervalUnit"
        }
    }

    public struct CrossRegionCopyRule: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the AWS KMS customer master key (CMK) to use for EBS encryption. If this parameter is not specified, your AWS managed CMK for EBS is used.
        public let cmkArn: String?
        /// Copy all user-defined tags from the source snapshot to the copied snapshot.
        public let copyTags: Bool?
        /// To encrypt a copy of an unencrypted snapshot if encryption by default is not enabled, enable encryption using this parameter. Copies of encrypted snapshots are encrypted, even if this parameter is false or if encryption by default is not enabled.
        public let encrypted: Bool
        /// The retention rule.
        public let retainRule: CrossRegionCopyRetainRule?
        /// The Amazon Resource Name (ARN) of the target AWS Outpost for the snapshot copies. If you specify an ARN, you must omit TargetRegion. You cannot specify a target Region and a target Outpost in the same rule.
        public let target: String?
        /// The target Region for the snapshot copies. If you specify a target Region, you must omit Target. You cannot specify a target Region and a target Outpost in the same rule.
        public let targetRegion: String?

        public init(cmkArn: String? = nil, copyTags: Bool? = nil, encrypted: Bool, retainRule: CrossRegionCopyRetainRule? = nil, target: String? = nil, targetRegion: String? = nil) {
            self.cmkArn = cmkArn
            self.copyTags = copyTags
            self.encrypted = encrypted
            self.retainRule = retainRule
            self.target = target
            self.targetRegion = targetRegion
        }

        public func validate(name: String) throws {
            try self.validate(self.cmkArn, name: "cmkArn", parent: name, max: 2048)
            try self.validate(self.cmkArn, name: "cmkArn", parent: name, min: 0)
            try self.validate(self.cmkArn, name: "cmkArn", parent: name, pattern: "arn:aws(-[a-z]{1,3}){0,2}:kms:([a-z]+-){2,3}\\d:\\d+:key/.*")
            try self.retainRule?.validate(name: "\(name).retainRule")
            try self.validate(self.target, name: "target", parent: name, max: 2048)
            try self.validate(self.target, name: "target", parent: name, min: 0)
            try self.validate(self.target, name: "target", parent: name, pattern: "^[\\w:\\-\\/\\*]+$")
            try self.validate(self.targetRegion, name: "targetRegion", parent: name, max: 16)
            try self.validate(self.targetRegion, name: "targetRegion", parent: name, min: 0)
            try self.validate(self.targetRegion, name: "targetRegion", parent: name, pattern: "([a-z]+-){2,3}\\d")
        }

        private enum CodingKeys: String, CodingKey {
            case cmkArn = "CmkArn"
            case copyTags = "CopyTags"
            case encrypted = "Encrypted"
            case retainRule = "RetainRule"
            case target = "Target"
            case targetRegion = "TargetRegion"
        }
    }

    public struct DeleteLifecyclePolicyRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "policyId", location: .uri(locationName: "policyId"))
        ]

        /// The identifier of the lifecycle policy.
        public let policyId: String

        public init(policyId: String) {
            self.policyId = policyId
        }

        public func validate(name: String) throws {
            try self.validate(self.policyId, name: "policyId", parent: name, max: 64)
            try self.validate(self.policyId, name: "policyId", parent: name, min: 0)
            try self.validate(self.policyId, name: "policyId", parent: name, pattern: "policy-[A-Za-z0-9]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteLifecyclePolicyResponse: AWSDecodableShape {
        public init() {}
    }

    public struct EncryptionConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the AWS KMS customer master key (CMK) to use for EBS encryption. If this parameter is not specified, your AWS managed CMK for EBS is used.
        public let cmkArn: String?
        /// To encrypt a copy of an unencrypted snapshot when encryption by default is not enabled, enable encryption using this parameter. Copies of encrypted snapshots are encrypted, even if this parameter is false or when encryption by default is not enabled.
        public let encrypted: Bool

        public init(cmkArn: String? = nil, encrypted: Bool) {
            self.cmkArn = cmkArn
            self.encrypted = encrypted
        }

        public func validate(name: String) throws {
            try self.validate(self.cmkArn, name: "cmkArn", parent: name, max: 2048)
            try self.validate(self.cmkArn, name: "cmkArn", parent: name, min: 0)
            try self.validate(self.cmkArn, name: "cmkArn", parent: name, pattern: "arn:aws(-[a-z]{1,3}){0,2}:kms:([a-z]+-){2,3}\\d:\\d+:key/.*")
        }

        private enum CodingKeys: String, CodingKey {
            case cmkArn = "CmkArn"
            case encrypted = "Encrypted"
        }
    }

    public struct EventParameters: AWSEncodableShape & AWSDecodableShape {
        /// The snapshot description that can trigger the policy. The description pattern is specified using a regular expression. The policy runs only if a snapshot with a description that matches the specified pattern is shared with your account. For example, specifying ^.*Created for policy: policy-1234567890abcdef0.*$ configures the policy to run only if snapshots created by policy policy-1234567890abcdef0 are shared with your account.
        public let descriptionRegex: String
        /// The type of event. Currently, only snapshot sharing events are supported.
        public let eventType: EventTypeValues
        /// The IDs of the AWS accounts that can trigger policy by sharing snapshots with your account. The policy only runs if one of the specified AWS accounts shares a snapshot with your account.
        public let snapshotOwner: [String]

        public init(descriptionRegex: String, eventType: EventTypeValues, snapshotOwner: [String]) {
            self.descriptionRegex = descriptionRegex
            self.eventType = eventType
            self.snapshotOwner = snapshotOwner
        }

        public func validate(name: String) throws {
            try self.validate(self.descriptionRegex, name: "descriptionRegex", parent: name, max: 1000)
            try self.validate(self.descriptionRegex, name: "descriptionRegex", parent: name, min: 0)
            try self.validate(self.descriptionRegex, name: "descriptionRegex", parent: name, pattern: "[\\p{all}]*")
            try self.snapshotOwner.forEach {
                try validate($0, name: "snapshotOwner[]", parent: name, max: 12)
                try validate($0, name: "snapshotOwner[]", parent: name, min: 12)
                try validate($0, name: "snapshotOwner[]", parent: name, pattern: "^[0-9]{12}$")
            }
            try self.validate(self.snapshotOwner, name: "snapshotOwner", parent: name, max: 50)
            try self.validate(self.snapshotOwner, name: "snapshotOwner", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case descriptionRegex = "DescriptionRegex"
            case eventType = "EventType"
            case snapshotOwner = "SnapshotOwner"
        }
    }

    public struct EventSource: AWSEncodableShape & AWSDecodableShape {
        /// Information about the event.
        public let parameters: EventParameters?
        /// The source of the event. Currently only managed AWS CloudWatch Events rules are supported.
        public let type: EventSourceValues

        public init(parameters: EventParameters? = nil, type: EventSourceValues) {
            self.parameters = parameters
            self.type = type
        }

        public func validate(name: String) throws {
            try self.parameters?.validate(name: "\(name).parameters")
        }

        private enum CodingKeys: String, CodingKey {
            case parameters = "Parameters"
            case type = "Type"
        }
    }

    public struct FastRestoreRule: AWSEncodableShape & AWSDecodableShape {
        /// The Availability Zones in which to enable fast snapshot restore.
        public let availabilityZones: [String]
        /// The number of snapshots to be enabled with fast snapshot restore.
        public let count: Int?
        /// The amount of time to enable fast snapshot restore. The maximum is 100 years. This is equivalent to 1200 months, 5200 weeks, or 36500 days.
        public let interval: Int?
        /// The unit of time for enabling fast snapshot restore.
        public let intervalUnit: RetentionIntervalUnitValues?

        public init(availabilityZones: [String], count: Int? = nil, interval: Int? = nil, intervalUnit: RetentionIntervalUnitValues? = nil) {
            self.availabilityZones = availabilityZones
            self.count = count
            self.interval = interval
            self.intervalUnit = intervalUnit
        }

        public func validate(name: String) throws {
            try self.availabilityZones.forEach {
                try validate($0, name: "availabilityZones[]", parent: name, max: 16)
                try validate($0, name: "availabilityZones[]", parent: name, min: 0)
                try validate($0, name: "availabilityZones[]", parent: name, pattern: "([a-z]+-){2,3}\\d[a-z]")
            }
            try self.validate(self.availabilityZones, name: "availabilityZones", parent: name, max: 10)
            try self.validate(self.availabilityZones, name: "availabilityZones", parent: name, min: 1)
            try self.validate(self.count, name: "count", parent: name, max: 1000)
            try self.validate(self.count, name: "count", parent: name, min: 1)
            try self.validate(self.interval, name: "interval", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZones = "AvailabilityZones"
            case count = "Count"
            case interval = "Interval"
            case intervalUnit = "IntervalUnit"
        }
    }

    public struct GetLifecyclePoliciesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "policyIds", location: .querystring(locationName: "policyIds")),
            AWSMemberEncoding(label: "resourceTypes", location: .querystring(locationName: "resourceTypes")),
            AWSMemberEncoding(label: "state", location: .querystring(locationName: "state")),
            AWSMemberEncoding(label: "tagsToAdd", location: .querystring(locationName: "tagsToAdd")),
            AWSMemberEncoding(label: "targetTags", location: .querystring(locationName: "targetTags"))
        ]

        /// The identifiers of the data lifecycle policies.
        public let policyIds: [String]?
        /// The resource type.
        public let resourceTypes: [ResourceTypeValues]?
        /// The activation state.
        public let state: GettablePolicyStateValues?
        /// The tags to add to objects created by the policy. Tags are strings in the format key=value. These user-defined tags are added in addition to the AWS-added lifecycle tags.
        public let tagsToAdd: [String]?
        /// The target tag for a policy. Tags are strings in the format key=value.
        public let targetTags: [String]?

        public init(policyIds: [String]? = nil, resourceTypes: [ResourceTypeValues]? = nil, state: GettablePolicyStateValues? = nil, tagsToAdd: [String]? = nil, targetTags: [String]? = nil) {
            self.policyIds = policyIds
            self.resourceTypes = resourceTypes
            self.state = state
            self.tagsToAdd = tagsToAdd
            self.targetTags = targetTags
        }

        public func validate(name: String) throws {
            try self.policyIds?.forEach {
                try validate($0, name: "policyIds[]", parent: name, max: 64)
                try validate($0, name: "policyIds[]", parent: name, min: 0)
                try validate($0, name: "policyIds[]", parent: name, pattern: "policy-[A-Za-z0-9]+")
            }
            try self.validate(self.resourceTypes, name: "resourceTypes", parent: name, max: 1)
            try self.validate(self.resourceTypes, name: "resourceTypes", parent: name, min: 1)
            try self.tagsToAdd?.forEach {
                try validate($0, name: "tagsToAdd[]", parent: name, max: 256)
                try validate($0, name: "tagsToAdd[]", parent: name, min: 0)
                try validate($0, name: "tagsToAdd[]", parent: name, pattern: "[\\p{all}]*")
            }
            try self.validate(self.tagsToAdd, name: "tagsToAdd", parent: name, max: 50)
            try self.validate(self.tagsToAdd, name: "tagsToAdd", parent: name, min: 0)
            try self.targetTags?.forEach {
                try validate($0, name: "targetTags[]", parent: name, max: 256)
                try validate($0, name: "targetTags[]", parent: name, min: 0)
                try validate($0, name: "targetTags[]", parent: name, pattern: "[\\p{all}]*")
            }
            try self.validate(self.targetTags, name: "targetTags", parent: name, max: 50)
            try self.validate(self.targetTags, name: "targetTags", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetLifecyclePoliciesResponse: AWSDecodableShape {
        /// Summary information about the lifecycle policies.
        public let policies: [LifecyclePolicySummary]?

        public init(policies: [LifecyclePolicySummary]? = nil) {
            self.policies = policies
        }

        private enum CodingKeys: String, CodingKey {
            case policies = "Policies"
        }
    }

    public struct GetLifecyclePolicyRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "policyId", location: .uri(locationName: "policyId"))
        ]

        /// The identifier of the lifecycle policy.
        public let policyId: String

        public init(policyId: String) {
            self.policyId = policyId
        }

        public func validate(name: String) throws {
            try self.validate(self.policyId, name: "policyId", parent: name, max: 64)
            try self.validate(self.policyId, name: "policyId", parent: name, min: 0)
            try self.validate(self.policyId, name: "policyId", parent: name, pattern: "policy-[A-Za-z0-9]+")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetLifecyclePolicyResponse: AWSDecodableShape {
        /// Detailed information about the lifecycle policy.
        public let policy: LifecyclePolicy?

        public init(policy: LifecyclePolicy? = nil) {
            self.policy = policy
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "Policy"
        }
    }

    public struct LifecyclePolicy: AWSDecodableShape {
        /// The local date and time when the lifecycle policy was created.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var dateCreated: Date?
        /// The local date and time when the lifecycle policy was last modified.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var dateModified: Date?
        /// The description of the lifecycle policy.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the IAM role used to run the operations specified by the lifecycle policy.
        public let executionRoleArn: String?
        /// The Amazon Resource Name (ARN) of the policy.
        public let policyArn: String?
        /// The configuration of the lifecycle policy
        public let policyDetails: PolicyDetails?
        /// The identifier of the lifecycle policy.
        public let policyId: String?
        /// The activation state of the lifecycle policy.
        public let state: GettablePolicyStateValues?
        /// The description of the status.
        public let statusMessage: String?
        /// The tags.
        public let tags: [String: String]?

        public init(dateCreated: Date? = nil, dateModified: Date? = nil, description: String? = nil, executionRoleArn: String? = nil, policyArn: String? = nil, policyDetails: PolicyDetails? = nil, policyId: String? = nil, state: GettablePolicyStateValues? = nil, statusMessage: String? = nil, tags: [String: String]? = nil) {
            self.dateCreated = dateCreated
            self.dateModified = dateModified
            self.description = description
            self.executionRoleArn = executionRoleArn
            self.policyArn = policyArn
            self.policyDetails = policyDetails
            self.policyId = policyId
            self.state = state
            self.statusMessage = statusMessage
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case dateCreated = "DateCreated"
            case dateModified = "DateModified"
            case description = "Description"
            case executionRoleArn = "ExecutionRoleArn"
            case policyArn = "PolicyArn"
            case policyDetails = "PolicyDetails"
            case policyId = "PolicyId"
            case state = "State"
            case statusMessage = "StatusMessage"
            case tags = "Tags"
        }
    }

    public struct LifecyclePolicySummary: AWSDecodableShape {
        /// The description of the lifecycle policy.
        public let description: String?
        /// The identifier of the lifecycle policy.
        public let policyId: String?
        /// The type of policy. EBS_SNAPSHOT_MANAGEMENT indicates that the policy manages the lifecycle of Amazon EBS snapshots. IMAGE_MANAGEMENT indicates that the policy manages the lifecycle of EBS-backed AMIs.
        public let policyType: PolicyTypeValues?
        /// The activation state of the lifecycle policy.
        public let state: GettablePolicyStateValues?
        /// The tags.
        public let tags: [String: String]?

        public init(description: String? = nil, policyId: String? = nil, policyType: PolicyTypeValues? = nil, state: GettablePolicyStateValues? = nil, tags: [String: String]? = nil) {
            self.description = description
            self.policyId = policyId
            self.policyType = policyType
            self.state = state
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case policyId = "PolicyId"
            case policyType = "PolicyType"
            case state = "State"
            case tags = "Tags"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri(locationName: "resourceArn"))
        ]

        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 0)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws(-[a-z]{1,3}){0,2}:dlm:[A-Za-z0-9_/.-]{0,63}:\\d+:policy/[0-9A-Za-z_-]{1,128}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// Information about the tags.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct Parameters: AWSEncodableShape & AWSDecodableShape {
        /// [EBS Snapshot Management – Instance policies only] Indicates whether to exclude the root volume from snapshots created using CreateSnapshots. The default is false.
        public let excludeBootVolume: Bool?
        /// Applies to AMI lifecycle policies only. Indicates whether targeted instances are rebooted when the lifecycle policy runs. true indicates that targeted instances are not rebooted when the policy runs. false indicates that target instances are rebooted when the policy runs. The default is true (instances are not rebooted).
        public let noReboot: Bool?

        public init(excludeBootVolume: Bool? = nil, noReboot: Bool? = nil) {
            self.excludeBootVolume = excludeBootVolume
            self.noReboot = noReboot
        }

        private enum CodingKeys: String, CodingKey {
            case excludeBootVolume = "ExcludeBootVolume"
            case noReboot = "NoReboot"
        }
    }

    public struct PolicyDetails: AWSEncodableShape & AWSDecodableShape {
        /// The actions to be performed when the event-based policy is triggered. You can specify only one action per policy. This parameter is required for event-based policies only. If you are creating a snapshot or AMI policy, omit this parameter.
        public let actions: [Action]?
        /// The event that triggers the event-based policy.  This parameter is required for event-based policies only. If you are creating a snapshot or AMI policy, omit this parameter.
        public let eventSource: EventSource?
        /// A set of optional parameters for snapshot and AMI lifecycle policies.  This parameter is required for snapshot and AMI policies only. If you are creating an event-based policy, omit this parameter.
        public let parameters: Parameters?
        /// The valid target resource types and actions a policy can manage. Specify EBS_SNAPSHOT_MANAGEMENT to create a lifecycle policy that manages the lifecycle of Amazon EBS snapshots. Specify IMAGE_MANAGEMENT to create a lifecycle policy that manages the lifecycle of EBS-backed AMIs. Specify EVENT_BASED_POLICY  to create an event-based policy that performs specific actions when a defined event occurs in your AWS account. The default is EBS_SNAPSHOT_MANAGEMENT.
        public let policyType: PolicyTypeValues?
        /// The location of the resources to backup. If the source resources are located in an AWS Region, specify CLOUD. If the source resources are located on an AWS Outpost in your account, specify OUTPOST.  If you specify OUTPOST, Amazon Data Lifecycle Manager backs up all resources of the specified type with matching target tags across all of the Outposts in your account.
        public let resourceLocations: [ResourceLocationValues]?
        /// The target resource type for snapshot and AMI lifecycle policies. Use VOLUME to create snapshots of individual volumes or use INSTANCE to create multi-volume snapshots from the volumes for an instance. This parameter is required for snapshot and AMI policies only. If you are creating an event-based policy, omit this parameter.
        public let resourceTypes: [ResourceTypeValues]?
        /// The schedules of policy-defined actions for snapshot and AMI lifecycle policies. A policy can have up to four schedules—one mandatory schedule and up to three optional schedules. This parameter is required for snapshot and AMI policies only. If you are creating an event-based policy, omit this parameter.
        public let schedules: [Schedule]?
        /// The single tag that identifies targeted resources for this policy. This parameter is required for snapshot and AMI policies only. If you are creating an event-based policy, omit this parameter.
        public let targetTags: [Tag]?

        public init(actions: [Action]? = nil, eventSource: EventSource? = nil, parameters: Parameters? = nil, policyType: PolicyTypeValues? = nil, resourceLocations: [ResourceLocationValues]? = nil, resourceTypes: [ResourceTypeValues]? = nil, schedules: [Schedule]? = nil, targetTags: [Tag]? = nil) {
            self.actions = actions
            self.eventSource = eventSource
            self.parameters = parameters
            self.policyType = policyType
            self.resourceLocations = resourceLocations
            self.resourceTypes = resourceTypes
            self.schedules = schedules
            self.targetTags = targetTags
        }

        public func validate(name: String) throws {
            try self.actions?.forEach {
                try $0.validate(name: "\(name).actions[]")
            }
            try self.validate(self.actions, name: "actions", parent: name, max: 1)
            try self.validate(self.actions, name: "actions", parent: name, min: 1)
            try self.eventSource?.validate(name: "\(name).eventSource")
            try self.validate(self.resourceLocations, name: "resourceLocations", parent: name, max: 1)
            try self.validate(self.resourceLocations, name: "resourceLocations", parent: name, min: 1)
            try self.validate(self.resourceTypes, name: "resourceTypes", parent: name, max: 1)
            try self.validate(self.resourceTypes, name: "resourceTypes", parent: name, min: 1)
            try self.schedules?.forEach {
                try $0.validate(name: "\(name).schedules[]")
            }
            try self.validate(self.schedules, name: "schedules", parent: name, max: 4)
            try self.validate(self.schedules, name: "schedules", parent: name, min: 1)
            try self.targetTags?.forEach {
                try $0.validate(name: "\(name).targetTags[]")
            }
            try self.validate(self.targetTags, name: "targetTags", parent: name, max: 50)
            try self.validate(self.targetTags, name: "targetTags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case actions = "Actions"
            case eventSource = "EventSource"
            case parameters = "Parameters"
            case policyType = "PolicyType"
            case resourceLocations = "ResourceLocations"
            case resourceTypes = "ResourceTypes"
            case schedules = "Schedules"
            case targetTags = "TargetTags"
        }
    }

    public struct RetainRule: AWSEncodableShape & AWSDecodableShape {
        /// The number of snapshots to retain for each volume, up to a maximum of 1000.
        public let count: Int?
        /// The amount of time to retain each snapshot. The maximum is 100 years. This is equivalent to 1200 months, 5200 weeks, or 36500 days.
        public let interval: Int?
        /// The unit of time for time-based retention.
        public let intervalUnit: RetentionIntervalUnitValues?

        public init(count: Int? = nil, interval: Int? = nil, intervalUnit: RetentionIntervalUnitValues? = nil) {
            self.count = count
            self.interval = interval
            self.intervalUnit = intervalUnit
        }

        public func validate(name: String) throws {
            try self.validate(self.count, name: "count", parent: name, max: 1000)
            try self.validate(self.count, name: "count", parent: name, min: 1)
            try self.validate(self.interval, name: "interval", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case count = "Count"
            case interval = "Interval"
            case intervalUnit = "IntervalUnit"
        }
    }

    public struct Schedule: AWSEncodableShape & AWSDecodableShape {
        /// Copy all user-defined tags on a source volume to snapshots of the volume created by this policy.
        public let copyTags: Bool?
        /// The creation rule.
        public let createRule: CreateRule?
        /// The rule for cross-Region snapshot copies. You can only specify cross-Region copy rules for policies that create snapshots in a Region. If the policy creates snapshots on an Outpost, then you cannot copy the snapshots to a Region or to an Outpost. If the policy creates snapshots in a Region, then snapshots can be copied to up to three Regions or Outposts.
        public let crossRegionCopyRules: [CrossRegionCopyRule]?
        /// The rule for enabling fast snapshot restore.
        public let fastRestoreRule: FastRestoreRule?
        /// The name of the schedule.
        public let name: String?
        /// The retention rule.
        public let retainRule: RetainRule?
        /// The rule for sharing snapshots with other AWS accounts.
        public let shareRules: [ShareRule]?
        /// The tags to apply to policy-created resources. These user-defined tags are in addition to the AWS-added lifecycle tags.
        public let tagsToAdd: [Tag]?
        /// A collection of key/value pairs with values determined dynamically when the policy is executed. Keys may be any valid Amazon EC2 tag key. Values must be in one of the two following formats: $(instance-id) or $(timestamp). Variable tags are only valid for EBS Snapshot Management – Instance policies.
        public let variableTags: [Tag]?

        public init(copyTags: Bool? = nil, createRule: CreateRule? = nil, crossRegionCopyRules: [CrossRegionCopyRule]? = nil, fastRestoreRule: FastRestoreRule? = nil, name: String? = nil, retainRule: RetainRule? = nil, shareRules: [ShareRule]? = nil, tagsToAdd: [Tag]? = nil, variableTags: [Tag]? = nil) {
            self.copyTags = copyTags
            self.createRule = createRule
            self.crossRegionCopyRules = crossRegionCopyRules
            self.fastRestoreRule = fastRestoreRule
            self.name = name
            self.retainRule = retainRule
            self.shareRules = shareRules
            self.tagsToAdd = tagsToAdd
            self.variableTags = variableTags
        }

        public func validate(name: String) throws {
            try self.createRule?.validate(name: "\(name).createRule")
            try self.crossRegionCopyRules?.forEach {
                try $0.validate(name: "\(name).crossRegionCopyRules[]")
            }
            try self.validate(self.crossRegionCopyRules, name: "crossRegionCopyRules", parent: name, max: 3)
            try self.validate(self.crossRegionCopyRules, name: "crossRegionCopyRules", parent: name, min: 0)
            try self.fastRestoreRule?.validate(name: "\(name).fastRestoreRule")
            try self.validate(self.name, name: "name", parent: name, max: 120)
            try self.validate(self.name, name: "name", parent: name, min: 0)
            try self.validate(self.name, name: "name", parent: name, pattern: "[0-9A-Za-z _-]+")
            try self.retainRule?.validate(name: "\(name).retainRule")
            try self.shareRules?.forEach {
                try $0.validate(name: "\(name).shareRules[]")
            }
            try self.validate(self.shareRules, name: "shareRules", parent: name, max: 1)
            try self.validate(self.shareRules, name: "shareRules", parent: name, min: 0)
            try self.tagsToAdd?.forEach {
                try $0.validate(name: "\(name).tagsToAdd[]")
            }
            try self.validate(self.tagsToAdd, name: "tagsToAdd", parent: name, max: 45)
            try self.validate(self.tagsToAdd, name: "tagsToAdd", parent: name, min: 0)
            try self.variableTags?.forEach {
                try $0.validate(name: "\(name).variableTags[]")
            }
            try self.validate(self.variableTags, name: "variableTags", parent: name, max: 45)
            try self.validate(self.variableTags, name: "variableTags", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case copyTags = "CopyTags"
            case createRule = "CreateRule"
            case crossRegionCopyRules = "CrossRegionCopyRules"
            case fastRestoreRule = "FastRestoreRule"
            case name = "Name"
            case retainRule = "RetainRule"
            case shareRules = "ShareRules"
            case tagsToAdd = "TagsToAdd"
            case variableTags = "VariableTags"
        }
    }

    public struct ShareRule: AWSEncodableShape & AWSDecodableShape {
        /// The IDs of the AWS accounts with which to share the snapshots.
        public let targetAccounts: [String]
        /// The period after which snapshots that are shared with other AWS accounts are automatically unshared.
        public let unshareInterval: Int?
        /// The unit of time for the automatic unsharing interval.
        public let unshareIntervalUnit: RetentionIntervalUnitValues?

        public init(targetAccounts: [String], unshareInterval: Int? = nil, unshareIntervalUnit: RetentionIntervalUnitValues? = nil) {
            self.targetAccounts = targetAccounts
            self.unshareInterval = unshareInterval
            self.unshareIntervalUnit = unshareIntervalUnit
        }

        public func validate(name: String) throws {
            try self.targetAccounts.forEach {
                try validate($0, name: "targetAccounts[]", parent: name, max: 12)
                try validate($0, name: "targetAccounts[]", parent: name, min: 12)
                try validate($0, name: "targetAccounts[]", parent: name, pattern: "^[0-9]{12}$")
            }
            try self.validate(self.targetAccounts, name: "targetAccounts", parent: name, min: 1)
            try self.validate(self.unshareInterval, name: "unshareInterval", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case targetAccounts = "TargetAccounts"
            case unshareInterval = "UnshareInterval"
            case unshareIntervalUnit = "UnshareIntervalUnit"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The tag key.
        public let key: String
        /// The tag value.
        public let value: String

        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 500)
            try self.validate(self.key, name: "key", parent: name, min: 0)
            try self.validate(self.key, name: "key", parent: name, pattern: "[\\p{all}]*")
            try self.validate(self.value, name: "value", parent: name, max: 500)
            try self.validate(self.value, name: "value", parent: name, min: 0)
            try self.validate(self.value, name: "value", parent: name, pattern: "[\\p{all}]*")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri(locationName: "resourceArn"))
        ]

        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String
        /// One or more tags.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 0)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws(-[a-z]{1,3}){0,2}:dlm:[A-Za-z0-9_/.-]{0,63}:\\d+:policy/[0-9A-Za-z_-]{1,128}$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "[\\p{all}]*")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri(locationName: "resourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring(locationName: "tagKeys"))
        ]

        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String
        /// The tag keys.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 2048)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 0)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws(-[a-z]{1,3}){0,2}:dlm:[A-Za-z0-9_/.-]{0,63}:\\d+:policy/[0-9A-Za-z_-]{1,128}$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 200)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateLifecyclePolicyRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "policyId", location: .uri(locationName: "policyId"))
        ]

        /// A description of the lifecycle policy.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the IAM role used to run the operations specified by the lifecycle policy.
        public let executionRoleArn: String?
        /// The configuration of the lifecycle policy. You cannot update the policy type or the resource type.
        public let policyDetails: PolicyDetails?
        /// The identifier of the lifecycle policy.
        public let policyId: String
        /// The desired activation state of the lifecycle policy after creation.
        public let state: SettablePolicyStateValues?

        public init(description: String? = nil, executionRoleArn: String? = nil, policyDetails: PolicyDetails? = nil, policyId: String, state: SettablePolicyStateValues? = nil) {
            self.description = description
            self.executionRoleArn = executionRoleArn
            self.policyDetails = policyDetails
            self.policyId = policyId
            self.state = state
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 500)
            try self.validate(self.description, name: "description", parent: name, min: 0)
            try self.validate(self.description, name: "description", parent: name, pattern: "[0-9A-Za-z _-]+")
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, max: 2048)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, min: 0)
            try self.validate(self.executionRoleArn, name: "executionRoleArn", parent: name, pattern: "arn:aws(-[a-z]{1,3}){0,2}:iam::\\d+:role/.*")
            try self.policyDetails?.validate(name: "\(name).policyDetails")
            try self.validate(self.policyId, name: "policyId", parent: name, max: 64)
            try self.validate(self.policyId, name: "policyId", parent: name, min: 0)
            try self.validate(self.policyId, name: "policyId", parent: name, pattern: "policy-[A-Za-z0-9]+")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case executionRoleArn = "ExecutionRoleArn"
            case policyDetails = "PolicyDetails"
            case state = "State"
        }
    }

    public struct UpdateLifecyclePolicyResponse: AWSDecodableShape {
        public init() {}
    }
}
